<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Java笔记 | Joey</title><meta name="keywords" content="Java"><meta name="author" content="方陈勇"><meta name="copyright" content="方陈勇"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Java基础笔记">
<meta property="og:type" content="article">
<meta property="og:title" content="Java笔记">
<meta property="og:url" content="https://fangchenyong.top/2019/07/18/Java-Java%E7%AC%94%E8%AE%B0/index.html">
<meta property="og:site_name" content="Joey">
<meta property="og:description" content="Java基础笔记">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG">
<meta property="article:published_time" content="2019-07-17T16:00:00.000Z">
<meta property="article:modified_time" content="2020-05-22T09:39:48.286Z">
<meta property="article:author" content="方陈勇">
<meta property="article:tag" content="Java">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="https://fangchenyong.top/2019/07/18/Java-Java%E7%AC%94%E8%AE%B0/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    jQuery: 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js',
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
    },
    fancybox: {
      js: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js',
      css: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isanchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = { 
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2020-05-22 17:39:48'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    })(window)</script><meta name="generator" content="Hexo 5.4.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="author-avatar"><img class="avatar-img" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/3FD9B055-6361-49B7-B8CE-5BA9144BD27F.JPG" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/archives/"><div class="headline">文章</div><div class="length-num">43</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/tags/"><div class="headline">标签</div><div class="length-num">51</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/categories/"><div class="headline">分类</div><div class="length-num">53</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> Home</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> Archives</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> Tags</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> Categories</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> List</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/music/"><i class="fa-fw fas fa-music"></i><span> Music</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> Movie</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> Link</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> About</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">Joey</a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> Home</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> Archives</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> Tags</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> Categories</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> List</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/music/"><i class="fa-fw fas fa-music"></i><span> Music</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> Movie</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> Link</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> About</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Java笔记</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2019-07-17T16:00:00.000Z" title="发表于 2019-07-18 00:00:00">2019-07-18</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2020-05-22T09:39:48.286Z" title="更新于 2020-05-22 17:39:48">2020-05-22</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java/">Java</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">7k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>24分钟</span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h2 id="java基础笔记"><a href="#java基础笔记" class="headerlink" title="java基础笔记"></a>java基础笔记</h2><ol>
<li><h4 id="基本数据类型和包装类型"><a href="#基本数据类型和包装类型" class="headerlink" title="基本数据类型和包装类型"></a>基本数据类型和包装类型</h4><blockquote>
<p>基本数据类型：short、int、long、double、float、char、string、boolean</p>
<p>包装类型：Short、Integer、Long、Double、Float、Char、String、Boolean</p>
<p>装箱：1. 手动装箱：Integer.valueOf(1) ;    2. 自动装箱：Integer i = 1;</p>
<p>拆箱：1. 手动拆箱：int j = i.intValue() ;    2. 自动拆箱：int j = i ;</p>
<p>JDK1.5开始为什么要引入包装类型：java是面向对象的语言，而基本的数据类型不具备面向对象的特性。</p>
<p>例：用Integer和int分别表示一个类的ID，进行非空判断的时候，Integer只要判断是否为null，int还要判断是否为0；</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Integer num1 = <span class="keyword">new</span> Integer(<span class="number">100</span>);</span><br><span class="line">Integer num2 = <span class="keyword">new</span> Integer(<span class="number">100</span>);</span><br><span class="line">System.out.println(<span class="string">&quot;num1==num2 &quot;</span> + (num1 == num2));</span><br><span class="line"></span><br><span class="line">Integer num3 = <span class="number">100</span>;</span><br><span class="line">Integer num4 = <span class="number">100</span>;</span><br><span class="line">System.out.println(<span class="string">&quot;num3==num4 &quot;</span> +(num3 == num4));</span><br><span class="line"></span><br><span class="line">Integer num5 = <span class="number">128</span>;</span><br><span class="line">Integer num6 = <span class="number">128</span>;</span><br><span class="line">System.out.println(<span class="string">&quot;num5==num6 &quot;</span> + (num5 == num6));</span><br><span class="line"></span><br><span class="line">Integer num7 = <span class="number">100</span>;</span><br><span class="line">Integer num8 = <span class="keyword">new</span> Integer(<span class="number">100</span>);</span><br><span class="line">System.out.println(<span class="string">&quot;num7==num8 &quot;</span> + (num7 == num8));</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> num9 = <span class="number">100</span>;</span><br><span class="line">Integer num10 = <span class="keyword">new</span> Integer(<span class="number">100</span>);</span><br><span class="line">Integer num11 = <span class="number">100</span>;</span><br><span class="line">System.out.println(<span class="string">&quot;num9==num10 &quot;</span> + (num9 == num10));</span><br><span class="line">System.out.println(<span class="string">&quot;num9==num11 &quot;</span> + (num9 == num11));</span><br><span class="line"></span><br><span class="line">结果：num1==num2 <span class="keyword">false</span>  </span><br><span class="line">	 num3==num4 <span class="keyword">true</span></span><br><span class="line">	 num5==num6 <span class="keyword">false</span></span><br><span class="line">	 num7==num8 <span class="keyword">false</span></span><br><span class="line">	 num9==num10 <span class="keyword">true</span></span><br><span class="line">	 num9==num11 <span class="keyword">true</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">源码：</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Integer <span class="title">valueOf</span><span class="params">(<span class="keyword">int</span> i)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (i &gt;= IntegerCache.low &amp;&amp; i &lt;= IntegerCache.high)</span><br><span class="line">            <span class="keyword">return</span> IntegerCache.cache[i + (-IntegerCache.low)];</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Integer(i);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">IntegerCache</span> </span>&#123;</span><br><span class="line">        <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> low = -<span class="number">128</span>;</span><br><span class="line">        <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> high;</span><br><span class="line">        <span class="keyword">static</span> <span class="keyword">final</span> Integer cache[];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">static</span> &#123;</span><br><span class="line">            <span class="comment">// high value may be configured by property</span></span><br><span class="line">            <span class="keyword">int</span> h = <span class="number">127</span>;</span><br><span class="line">            String integerCacheHighPropValue =</span><br><span class="line">                sun.misc.VM.getSavedProperty(<span class="string">&quot;java.lang.Integer.IntegerCache.high&quot;</span>);</span><br><span class="line">            <span class="keyword">if</span> (integerCacheHighPropValue != <span class="keyword">null</span>) &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="keyword">int</span> i = parseInt(integerCacheHighPropValue);</span><br><span class="line">                    i = Math.max(i, <span class="number">127</span>);</span><br><span class="line">                    <span class="comment">// Maximum array size is Integer.MAX_VALUE</span></span><br><span class="line">                    h = Math.min(i, Integer.MAX_VALUE - (-low) -<span class="number">1</span>);</span><br><span class="line">                &#125; <span class="keyword">catch</span>( NumberFormatException nfe) &#123;</span><br><span class="line">                    <span class="comment">// If the property cannot be parsed into an int, ignore it.</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            high = h;</span><br><span class="line"></span><br><span class="line">            cache = <span class="keyword">new</span> Integer[(high - low) + <span class="number">1</span>];</span><br><span class="line">            <span class="keyword">int</span> j = low;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k = <span class="number">0</span>; k &lt; cache.length; k++)</span><br><span class="line">                cache[k] = <span class="keyword">new</span> Integer(j++);</span><br><span class="line"></span><br><span class="line">            <span class="comment">// range [-128, 127] must be interned (JLS7 5.1.7)</span></span><br><span class="line">            <span class="keyword">assert</span> IntegerCache.high &gt;= <span class="number">127</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">private</span> <span class="title">IntegerCache</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    &#125;</span><br><span class="line">分析：</span><br><span class="line"><span class="number">1.</span>==对于对象来说比较的是对象的地址，两个新<span class="keyword">new</span>的对象地址不同，输出<span class="keyword">false</span>。</span><br><span class="line"><span class="number">2.</span>jvm在初始化的时候，会将低值（-<span class="number">128</span>）到高值（默认<span class="number">127</span>）之间的数字加载到内存中。低值是固定的，高值是可变的。在java程序执行的时候加上 -XX:AutoBoxCacheMax=&lt;size&gt; 的参数即可。缓如果初始化的数字是-<span class="number">128</span>~<span class="number">127</span>之间就会引用内存中的地址，输出<span class="keyword">true</span>。</span><br><span class="line"><span class="number">3.</span>同上。</span><br><span class="line"><span class="number">4.</span>num7是引用的本地内存地址，而num8是<span class="keyword">new</span>出来的，所以地址不同，输出<span class="keyword">false</span>。</span><br><span class="line"><span class="number">5.</span>包装类Integer和基本数据类型<span class="keyword">int</span>类型比较时，会自动拆箱为<span class="keyword">int</span>类型比较，实际上就变成两个基本的数据类型<span class="keyword">int</span>类型进行比较，而基本类型==比较的是值而不是地址，所以输出<span class="keyword">true</span>。</span><br><span class="line"><span class="number">6.</span>同上，即使是新<span class="keyword">new</span>出来的地址不同，但是最终拆箱为<span class="keyword">int</span>类型比较值是否相等，所以输出<span class="keyword">true</span>。</span><br></pre></td></tr></table></figure></blockquote>
</li>
<li><p>“==”和“equals()” 方法区别</p>
<blockquote>
<p><strong>变量分为基本数据类型和引用数据类型</strong></p>
<p>1）对于==，比较的是值是否相等</p>
<p>​    如果作用于基本数据类型的变量，则直接比较其存储的 “值”是否相等；</p>
<p>　　如果作用于引用类型的变量，则比较的是所指向的对象的地址</p>
<p>2）对于equals方法，注意：equals方法不能作用于基本数据类型的变量，equals继承Object类，比较的是是否是同一个对象</p>
<p>　　如果没有对equals方法进行重写，则比较的是引用类型的变量所指向的对象的地址；</p>
<p>　　诸如String、Date等类对equals方法进行了重写的话，比较的是所指向的对象的内容。</p>
</blockquote>
</li>
<li><p>String、StringBuilder、StringBuffer区别</p>
<blockquote>
<p>在这方面运行速度快慢为：StringBuilder &gt; StringBuffer &gt; String</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">1.</span>String底层使用<span class="keyword">final</span>关键字修饰的数组，因此不可变</span><br><span class="line">    <span class="comment">/** The value is used for character storage. */</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">char</span> value[];</span><br><span class="line"><span class="number">2.</span>StringBuilder继承AbstractStringBuilder抽象类使用的是普通数组所以可以改变。</span><br><span class="line">     <span class="comment">/** The value is used for character storage.*/</span></span><br><span class="line">     <span class="keyword">char</span>[] value;</span><br><span class="line"><span class="number">3.</span>StringBuffer继承AbstractStringBuilder抽象类使用的是普通数组所以可以改变。并且与StringBuilder重写的方法不同，方法添加了<span class="keyword">synchronized</span>关键字，线程安全但是效率低。</span><br></pre></td></tr></table></figure>

<blockquote>
<p>String为字符串常量，而StringBuilder和StringBuffer均为字符串变量，即String对象一旦创建之后该对象是不可更改的，但后两者的对象是变量，是可以更改的。</p>
<p>String：适用于少量的字符串操作的情况</p>
<p>StringBuilder：适用于单线程下在字符缓冲区进行大量操作的情况</p>
<p>StringBuffer：适用多线程下在字符缓冲区进行大量操作的情况</p>
</blockquote>
</li>
<li><h4 id="java中的集合"><a href="#java中的集合" class="headerlink" title="java中的集合"></a>java中的集合</h4><blockquote>
<p>java中的集合分类存储value（继承Collection接口）和存储key-value（继承）形式。</p>
<p><strong>存储值：</strong>List、Set</p>
<blockquote>
<p>List是有序的，可以重复的。</p>
<p>Set是无序的，不可以重复的。根据equals和hascode判断，也就是如果一个对象要存储在Set中，必须重写equals和hasCode方法。</p>
</blockquote>
<p><strong>存储键值：</strong>Map</p>
</blockquote>
</li>
<li><h4 id="ArrayList和LinkedList的区别和使用场景"><a href="#ArrayList和LinkedList的区别和使用场景" class="headerlink" title="ArrayList和LinkedList的区别和使用场景"></a>ArrayList和LinkedList的区别和使用场景</h4><blockquote>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">1.</span>ArrayList底层使用的是数组。</span><br><span class="line">	<span class="keyword">transient</span> Object[] elementData; </span><br><span class="line"><span class="number">2.</span>LinkedList底层使用的是链表。</span><br><span class="line">	<span class="keyword">transient</span> Node&lt;E&gt; first;</span><br><span class="line">	<span class="keyword">transient</span> Node&lt;E&gt; last;</span><br></pre></td></tr></table></figure>
</blockquote>
<blockquote>
<p><strong>区别：</strong></p>
<p>数组查询特定元素快，而插入、删除和修改比较慢，因为数组在内存中是一块连续的内存，如果是插入或删除需要移动内存。</p>
<p>链表在内存中是不连续的，在当前元素中存放的是下一个或者上一个元素的地址。查询时需要从头部开始查找至尾部，效率低。而插入时不需要移动内存，只需要改变节点指针即可。所以插入或删除效率高。</p>
<p><strong>使用场景：</strong></p>
<p>ArrayList使用在查询比较多，但是插入和删除比较少的情况，</p>
<p>LinkedList使用在查询比较少，但是插入和删除比较多的情况。</p>
</blockquote>
</li>
<li><h4 id="HashMap和Hashtable的区别"><a href="#HashMap和Hashtable的区别" class="headerlink" title="HashMap和Hashtable的区别"></a>HashMap和Hashtable的区别</h4><blockquote>
<p><strong>相同点：</strong>都可以用来存储Key-Value类型数据</p>
<p><strong>不同点：</strong></p>
<ol>
<li><p>HashMap可以使用null值作为key或者value，而Hashtable不行。</p>
</li>
<li><p>HashMap是线程不安全的，效率高。而Hashtable是线程安全的，效率低。</p>
</li>
<li><p>HashMap继承了AbstractMap抽象类同时实现Map, Cloneable, Serializable接口，而Hashtable继承了Dictionary抽象类同时实现Map, Cloneable, Serializable接口。</p>
</li>
</ol>
<p><strong>线程安全又要效率高？ConcurrentHashMap</strong></p>
<p>通过把整个Map分为N个Segment（类似于Hashtable）,可以提供相关的线程安全，又可以提升效率，默认提升16倍。</p>
</blockquote>
</li>
<li><h4 id="实现一个拷贝文件的工具类使用字节流还是字符流"><a href="#实现一个拷贝文件的工具类使用字节流还是字符流" class="headerlink" title="实现一个拷贝文件的工具类使用字节流还是字符流"></a>实现一个拷贝文件的工具类使用字节流还是字符流</h4><blockquote>
<p>我们拷贝的文件不确定是只包含字符流，有可能有字节流（图片、声音、图像等），为考虑到通用性，要使用字节流。</p>
</blockquote>
</li>
<li><h4 id="线程的几种实现方式"><a href="#线程的几种实现方式" class="headerlink" title="线程的几种实现方式"></a>线程的几种实现方式</h4><blockquote>
<ol>
<li><p>通过继承Thread类实现一个线程</p>
</li>
<li><p>通过实现Runnable接口实现一个线程</p>
</li>
<li><p>通过实现callable接口，重写call函数</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.concurrent.Callable;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.FutureTask;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ThreadDemo</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// =======  创建线程方式一  开始 (Thread是一个类继承了Runnable接口) =======</span></span><br><span class="line">        Thread thread = <span class="keyword">new</span> Thread()&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;<span class="comment">//该方法中写我们业务代码</span></span><br><span class="line"></span><br><span class="line">                <span class="keyword">while</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line">                    <span class="keyword">try</span> &#123;</span><br><span class="line">                        Thread.sleep(<span class="number">1000</span>);<span class="comment">//休眠1000毫秒(就是1秒)</span></span><br><span class="line">                    &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                        e.printStackTrace();</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="comment">//打印当前线程名称</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;创建线程方式一,打印线程名称: &quot;</span>+Thread.currentThread().getName());</span><br><span class="line"></span><br><span class="line">                    <span class="comment">//打印当前线程名称,这里采用this来获取,在某些时候这里并不适用,推荐使用上面一种方式</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;创建线程方式一,通过this调用getName方法,打印线程名称: &quot;</span>+<span class="keyword">this</span>.getName());</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        thread.start();<span class="comment">//启动线程</span></span><br><span class="line">        <span class="comment">// =======  创建线程方式一  结束  =======</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// =======  创建线程方式二开始  (Runnable是一个接口)=======</span></span><br><span class="line">        Thread thread2 = <span class="keyword">new</span> Thread(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line"></span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;<span class="comment">//该方法中写我们业务代码</span></span><br><span class="line">                <span class="keyword">while</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line">                    <span class="keyword">try</span> &#123;</span><br><span class="line">                        Thread.sleep(<span class="number">1000</span>);<span class="comment">//休眠1000毫秒(就是1秒)</span></span><br><span class="line">                    &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                        e.printStackTrace();</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="comment">//打印当前线程名称</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;创建线程方式二,打印线程名称: &quot;</span>+Thread.currentThread().getName());</span><br><span class="line"></span><br><span class="line">                    <span class="comment">//TODO 这种方式就不适合上面打印2的方式通过this来调用获取当前线程名称的方法</span></span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">        thread2.start();<span class="comment">//启动线程</span></span><br><span class="line">        <span class="comment">// =======  创建线程方式二  结束  =======</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="comment">// =======  创建线程方式三 开始  =======</span></span><br><span class="line">        FutureTask&lt;Integer&gt; thread3 = <span class="keyword">new</span> FutureTask&lt;&gt;(<span class="keyword">new</span> Callable&lt;Integer&gt;() &#123;</span><br><span class="line"></span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> Integer <span class="title">call</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">                <span class="keyword">int</span> count =<span class="number">0</span>;  </span><br><span class="line">                <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;=<span class="number">10</span>;i++)&#123;  </span><br><span class="line">                    count=count+i;  </span><br><span class="line">                &#125;  </span><br><span class="line">                <span class="comment">//打印当前线程名称</span></span><br><span class="line">                System.out.println(<span class="string">&quot;创建线程方式三,打印线程名称: &quot;</span>+Thread.currentThread().getName());</span><br><span class="line">                <span class="keyword">return</span> count; <span class="comment">//返回值   </span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);  </span><br><span class="line"></span><br><span class="line">        <span class="keyword">new</span> Thread(thread3,<span class="string">&quot;这是线程名称&quot;</span>).start();<span class="comment">//启动线程</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;创建线程方式三,打印返回值:&quot;</span>+ thread3.get());<span class="comment">//打印返回值</span></span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; </span><br><span class="line">     <span class="comment">// =======  创建线程方式三 结束  =======</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>区别：</strong></p>
<ul>
<li><p>采用继承Thread类方式：</p>
<p>​    优点：编写简单，如果需要访问当前线程，无需使用Thread.currentThread()方法，直接使用this，即可获得当前线程。</p>
<p>​    缺点：因为线程类已经继承了Thread类，所以不能再继承其他的父类。</p>
</li>
<li><p>采用实现Runnable接口方式：</p>
<p>​    优点：线程类只是实现了Runable接口，还可以继承其他的类。在这种方式下，可以多个线程共享同一个目标对象，所以非常适合多个相同线程来处理同一份资源的情况，从而可以将CPU代码和数据分开，形成清晰的模型，较好地体现了面向对象的思想。</p>
<p>​    缺点：编程稍微复杂，如果需要访问当前线程，必须使用Thread.currentThread()方法。</p>
</li>
</ul>
</li>
</ol>
</blockquote>
</li>
<li><h4 id="线程池"><a href="#线程池" class="headerlink" title="线程池"></a>线程池</h4><blockquote>
<ol>
<li><strong>newCachedThreadPool</strong></li>
</ol>
<p>创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。</p>
<p>这种类型的线程池特点是：</p>
<ul>
<li>工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。</li>
<li>如果长时间没有往线程池中提交任务，即如果工作线程空闲了指定的时间(默认为1分钟)，则该工作线程将自动终止。终止后，如果你又提交了新的任务，则线程池重新创建一个工作线程。</li>
<li>在使用CachedThreadPool时，一定要注意控制任务的数量，否则，由于大量线程同时运行，很有会造成系统瘫痪。</li>
</ul>
<p>示例代码如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> test;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.ExecutorService;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.Executors;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ThreadPoolExecutorTest</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();</span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">			<span class="keyword">final</span> <span class="keyword">int</span> index = i;</span><br><span class="line">			<span class="keyword">try</span> &#123;</span><br><span class="line">				Thread.sleep(index * <span class="number">1000</span>);</span><br><span class="line">			&#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">				e.printStackTrace();</span><br><span class="line">			&#125;</span><br><span class="line">			cachedThreadPool.execute(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">				<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">					System.out.println(index);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="2">
<li><strong>newFixedThreadPool</strong></li>
</ol>
<p>创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程，如果工作线程数量达到线程池初始的最大数，则将提交的任务存入到池队列中。</p>
<p>FixedThreadPool是一个典型且优秀的线程池，它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是，在线程池空闲时，即线程池中没有可运行任务时，它不会释放工作线程，还会占用一定的系统资源。</p>
<p>示例代码如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> test;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.ExecutorService;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.Executors;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ThreadPoolExecutorTest</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		ExecutorService fixedThreadPool = Executors.newFixedThreadPool(<span class="number">3</span>);</span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">			<span class="keyword">final</span> <span class="keyword">int</span> index = i;</span><br><span class="line">			fixedThreadPool.execute(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">				<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">					<span class="keyword">try</span> &#123;</span><br><span class="line">						System.out.println(index);</span><br><span class="line">						Thread.sleep(<span class="number">2000</span>);</span><br><span class="line">					&#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">						e.printStackTrace();</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>因为线程池大小为3，每个任务输出index后sleep 2秒，所以每两秒打印3个数字。<br>定长线程池的大小最好根据系统资源进行设置如Runtime.getRuntime().availableProcessors()</p>
<ol start="3">
<li><strong>newSingleThreadExecutor</strong></li>
</ol>
<p>创建一个单线程化的Executor，即只创建唯一的工作者线程来执行任务，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束，会有另一个取代它，保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务，并且在任意给定的时间不会有多个线程是活动的。</p>
<p>示例代码如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> test;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.ExecutorService;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.Executors;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ThreadPoolExecutorTest</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();</span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">			<span class="keyword">final</span> <span class="keyword">int</span> index = i;</span><br><span class="line">			singleThreadExecutor.execute(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">				<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">					<span class="keyword">try</span> &#123;</span><br><span class="line">						System.out.println(index);</span><br><span class="line">						Thread.sleep(<span class="number">2000</span>);</span><br><span class="line">					&#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">						e.printStackTrace();</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125; </span><br></pre></td></tr></table></figure>

<ol start="4">
<li><strong>newScheduleThreadPool</strong></li>
</ol>
<p>创建一个定长的线程池，而且支持定时的以及周期性的任务执行，支持定时及周期性任务执行。</p>
<p>延迟3秒执行，延迟执行示例代码如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> test;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.Executors;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.ScheduledExecutorService;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.TimeUnit;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ThreadPoolExecutorTest</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(<span class="number">5</span>);</span><br><span class="line">		scheduledThreadPool.schedule(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">			<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">				System.out.println(<span class="string">&quot;delay 3 seconds&quot;</span>);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;, <span class="number">3</span>, TimeUnit.SECONDS);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>表示延迟1秒后每3秒执行一次，定期执行示例代码如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> test;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.Executors;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.ScheduledExecutorService;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.TimeUnit;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ThreadPoolExecutorTest</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(<span class="number">5</span>);</span><br><span class="line">		scheduledThreadPool.scheduleAtFixedRate(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">			<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">				System.out.println(<span class="string">&quot;delay 1 seconds, and excute every 3 seconds&quot;</span>);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;, <span class="number">1</span>, <span class="number">3</span>, TimeUnit.SECONDS);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></blockquote>
</li>
<li><h4 id="使用线程池的风险，为什么使用线程池"><a href="#使用线程池的风险，为什么使用线程池" class="headerlink" title="使用线程池的风险，为什么使用线程池"></a>使用线程池的风险，为什么使用线程池</h4></li>
</ol>
<blockquote>
<p><strong>风险：</strong></p>
<ol>
<li>死锁</li>
<li>资源不足</li>
<li>并发错误</li>
<li>线程泄漏</li>
<li>请求过载</li>
</ol>
<p><strong>作用：</strong>（连接池同理）</p>
<ol>
<li>限定线程的个数，不会由于线程过多而导致系统运行缓慢或崩溃</li>
<li>线程池不需要每次去创建或销毁，节约资源，响应速度快</li>
</ol>
</blockquote>
<ol start="11">
<li><h4 id="设计模式"><a href="#设计模式" class="headerlink" title="设计模式"></a>设计模式</h4><blockquote>
<p><strong>常用的设计模式：</strong></p>
<ol>
<li><p>单例模式（饱汉模式、饿汉模式）：</p>
<p>（1）构造方法私有化，在除了自己类中其他地方都不能创建</p>
<p>（2）在自己的类中创建一个单实例（饱汉模式是一出来就创建单实例，而饿汉模式需要用到的时候才创建）</p>
<p>（3）提供一个方法或获取该实例对象（创建时需要进行方法同步）</p>
</li>
<li><p>工厂模式：SpringIOC使用的就是工厂模式，对象的创建交给一个工厂  创建。</p>
</li>
<li><p>代理模式：SpringAOP使用的就是动态代理。</p>
</li>
</ol>
</blockquote>
</li>
</ol>
<h2 id="javaWeb笔记"><a href="#javaWeb笔记" class="headerlink" title="javaWeb笔记"></a>javaWeb笔记</h2><ol>
<li><h4 id="Http-Get和Post请求的区别"><a href="#Http-Get和Post请求的区别" class="headerlink" title="Http Get和Post请求的区别"></a>Http Get和Post请求的区别</h4><blockquote>
<p><strong>相同点：</strong></p>
<p>Get和Post请求都是Http请求方式，用户通过不同的Http请求对资源实现不同的操作。GET，POST，PUT，DELETE对应着对资源的查，改，增，删4个操作，GET一般用于获取/查询资源信息，而POST用于更新资源信息。</p>
<p><strong>区别：</strong></p>
<ol>
<li>GET请求提交的数据会在地址栏显示出来，而POST请求地址栏不会改变，数据放置在HTTP包体中。</li>
<li>传输数据的大小不同，GET由于浏览器对地址长度的限制导致传输的数据有限制，而POST不会。</li>
<li>GET提交的数据会在地址中显示出来，安全性较低，而POST则不会。</li>
</ol>
</blockquote>
</li>
<li><h4 id="servlet的理解"><a href="#servlet的理解" class="headerlink" title="servlet的理解"></a>servlet的理解</h4><blockquote>
<p>Servlet 是用java编写的服务器端程序，而这些Servlet都要实现Servlet接口。主要用于交互式地浏览和修改数据，生成动态Web内容。Servlet运行于支持java的web容器中。</p>
<p>HttpServlet重写doGet和doPost方法或者service方法完成对get和post请求的响应。</p>
</blockquote>
</li>
<li><h4 id="servlet的生命周期"><a href="#servlet的生命周期" class="headerlink" title="servlet的生命周期"></a>servlet的生命周期</h4><blockquote>
<ol>
<li>加载Servlet的class</li>
<li>实例化Servlet</li>
<li>调用Servlet的init完成实例化</li>
<li>运行service方法，响应doGet或doPost请求</li>
<li>调用destory方法销毁实例</li>
</ol>
</blockquote>
</li>
<li><h4 id="Servlet-API中forward-和redirect-区别"><a href="#Servlet-API中forward-和redirect-区别" class="headerlink" title="Servlet API中forward() 和redirect()区别"></a>Servlet API中forward() 和redirect()区别</h4><blockquote>
<p>forward：转发，地址不变，服务端跳转</p>
<p>redirect：重定向，地址改变，客户端跳转</p>
</blockquote>
</li>
<li><h4 id="Session和Cookie区别"><a href="#Session和Cookie区别" class="headerlink" title="Session和Cookie区别"></a>Session和Cookie区别</h4><blockquote>
<p><strong>相同点：</strong></p>
<p>Session和cookie都是会话跟踪技术。Cookie通过在客户端记录信息确定用户身份，Session通过在服务端记录信息确定用户身份。但是Session是实现依赖于Cookie，sessionId（session的唯一标识需要存放在客户端）</p>
<p><strong>区别：</strong></p>
<ol>
<li><p>Cookie数据存放在客户端浏览器，Session存放在服务器上</p>
</li>
<li><p>Cookie安全性较Session差</p>
</li>
<li><p>Session运行时间久会占用较多服务器内存，影响服务器性能</p>
</li>
<li><p>单个Cookie保存的数据不能超过4K，很多浏览器都限制一个站点最多保存20个Cookie</p>
</li>
<li><p>登录信息等重要信息存放在Session中，安全性较高</p>
<p>其他信息如果需要保留，存在Cookie中（比如购物车的实现，但是Cookie在客户端是可以禁用的，所以可以采用cookie+数据库方式实现）</p>
</li>
</ol>
</blockquote>
</li>
<li><h4 id="MVC的各部分都有哪些技术来实现"><a href="#MVC的各部分都有哪些技术来实现" class="headerlink" title="MVC的各部分都有哪些技术来实现"></a>MVC的各部分都有哪些技术来实现</h4><blockquote>
<ul>
<li>M（Model） 模型     javabean……</li>
<li>V（View）     视图     html、jsp、freemarker、thymeleaf……</li>
<li>C（Control）控制器 Servlet、Action……</li>
</ul>
</blockquote>
</li>
</ol>
<h2 id="数据库笔记"><a href="#数据库笔记" class="headerlink" title="数据库笔记"></a>数据库笔记</h2><ol>
<li><h4 id="数据库分类"><a href="#数据库分类" class="headerlink" title="数据库分类"></a>数据库分类</h4><blockquote>
<ul>
<li><p>关系型数据库</p>
<blockquote>
<p> MySql、Oracle、SqlServer……</p>
</blockquote>
</li>
<li><p>非关系型数据库</p>
<blockquote>
<p>redis、memcache、mogodb、hadoop……</p>
</blockquote>
</li>
</ul>
</blockquote>
</li>
<li><h4 id="关系型数据库三范式"><a href="#关系型数据库三范式" class="headerlink" title="关系型数据库三范式"></a>关系型数据库三范式</h4><blockquote>
<ol>
<li><p>第一范式（1NF)所谓第一范式（1NF）是指<strong>数据库表的每一列都是不可分割的基本数据项，同一列中不能有多个值，即实体中的某个属性不能有多个值或者不能有重复的属性</strong>。如果出现重复的属性，就可能需要定义一个新的实体，新的实体由重复的属性构成，新实体与原实体之间为一对多关系。在第一范式（1NF）中表的每一行只包含一个实例的信息。</p>
<p>在任何一个关系数据库中，第一范式（1NF）是对关系模式的基本要求，不满足第一范式（1NF）的数据库就不是关系数据库。理解注释：列不可分。</p>
</li>
<li><p>第二范式（2NF)第二范式（2NF）是在第一范式（1NF）的基础上建立起来的，即满足第二范式（2NF）必须先满足第一范式（1NF）。第二范式（2NF）要求<strong>数据库表中的每个实例或行必须可以被惟一的区分</strong>。为实现区分通常需要为表加上一个列，以存储各个实例的惟一标识。要求实体的属性完全依赖于主关键字。理解注释：不能部分依赖。即：一张表存在组合主键时，其他非主键字段不能部分依赖。</p>
</li>
<li><p>第三范式（3NF)满足第三范式（3NF）必须先满足第二范式（2NF）。简而言之，第三范式（3NF）要求<strong>一个数据库表中不包含已在其它表中已包含的非主关键字信息</strong>。在第二范式的基础上，数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。理解注释：不能存在传递依赖。即：除主键外，其他字段必须依赖主键。</p>
</li>
</ol>
</blockquote>
</li>
<li><h4 id="事务四个基本特征ACID特性"><a href="#事务四个基本特征ACID特性" class="headerlink" title="事务四个基本特征ACID特性"></a>事务四个基本特征ACID特性</h4><blockquote>
<p>​    事务是并发控制的单位，使用户定义的一个操作序列。这些操作要么都做，要么都不做，是一个不可分割的工作单位。事务(transaction)所应该具有的四个特性：原子性（Atomicity）、一致性（Consistency）、隔离性（Isolation）、持久性（Durability）.这是可靠数据库所应具备的几个特性.</p>
<ul>
<li><p>原子性</p>
<blockquote>
<p>整个事务中的所有操作，要么全部完成，要么全部不完成，不可能停滞在中间某个环节。事务在执行过程中发生错误，会被回滚（Rollback）到事务开始前的状态，就像这个事务从来没有执行过一样。</p>
</blockquote>
</li>
<li><p>一致性</p>
<blockquote>
<p>在事务开始之前和事务结束以后，数据库的完整性约束没有被破坏。</p>
</blockquote>
</li>
<li><p>隔离性</p>
<blockquote>
<p>隔离状态执行事务，使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务，运行在相同的时间内，执行相同的功能，事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化，为了防止事务操作间的混淆，必须串行化或序列化请求，使得在同一时间仅有一个请求用于同一数据。</p>
</blockquote>
</li>
<li><p>持久性</p>
<blockquote>
<p>在事务完成以后，该事务所对数据库所作的更改便持久的保存在数据库之中，并不会被回滚。</p>
</blockquote>
</li>
</ul>
</blockquote>
</li>
<li><h4 id="MySql数据库默认的最大连接数"><a href="#MySql数据库默认的最大连接数" class="headerlink" title="MySql数据库默认的最大连接数"></a>MySql数据库默认的最大连接数</h4><blockquote>
<p>特定服务器上的数据库只能支持一定数目同时连接，这时候需要我们设置最大连接数（最多同时服务多少连接），在my.ini中查看设置</p>
<figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="comment"># The maximum amount of concurrent sessions the MySQL server will</span></span><br><span class="line"><span class="comment"># allow. One of these connections will be reserved for a user with</span></span><br><span class="line"><span class="comment"># SUPER privileges to allow the administrator to login even if the</span></span><br><span class="line"><span class="comment"># connection limit has been reached.</span></span><br><span class="line"><span class="attr">max_connections</span>=<span class="number">151</span></span><br></pre></td></tr></table></figure></blockquote>
</li>
<li><h4 id="MySql分页、Oracle分页和SqlServer分页"><a href="#MySql分页、Oracle分页和SqlServer分页" class="headerlink" title="MySql分页、Oracle分页和SqlServer分页"></a><del>MySql分页、Oracle分页和SqlServer分页</del></h4><blockquote>
<p>MySql使用limit关键字来分页</p>
<p>Oracle使用rownum</p>
<p>SqlServer使用top</p>
</blockquote>
</li>
<li><h4 id="触发器使用场景"><a href="#触发器使用场景" class="headerlink" title="触发器使用场景"></a><strong>触发器使用场景</strong></h4><blockquote>
</blockquote>
</li>
</ol>
<h2 id="前端笔记"><a href="#前端笔记" class="headerlink" title="前端笔记"></a>前端笔记</h2><h2 id="框架笔记"><a href="#框架笔记" class="headerlink" title="框架笔记"></a>框架笔记</h2><ol>
<li><h4 id="SpringMVC执行流程"><a href="#SpringMVC执行流程" class="headerlink" title="SpringMVC执行流程"></a>SpringMVC执行流程</h4><blockquote>
<ol>
<li>用户向服务器发送请求，请求被Spring前端控制器DispatcherServlet拦截</li>
<li>DispatcherServlet对请求的URL进行解析，得到请求资源标识符（URL）。然后根据URI调用HandlerMapping获的该Handler配置的所有相关对象，最后以HandlerExecutionChain对象的形式返回</li>
<li>DispatcherServlet根据获得的Handler，选择一个合适的HandlerAdapter适配器，提取Request中的模型数据，填充Handler入参，开始执行Handler（Controller），Handler执行完成后，向DispatcherServlet返回一个ModelAndVIew对象</li>
<li>DispatcherServlet根据返回的ModelAndVIew，选择一个合适的ViewResolver视图解析器</li>
<li>通过ViewResolver结合Model和View。来渲染视图，DispatcherServlet将渲染结果返回给客户端</li>
</ol>
</blockquote>
</li>
<li><h4 id="Struts2和SpringMVC区别"><a href="#Struts2和SpringMVC区别" class="headerlink" title="Struts2和SpringMVC区别"></a>Struts2和SpringMVC区别</h4><blockquote>
<ol>
<li>Struts2的前端控制器是Filter，SpringMVC是Servlet</li>
<li>SpringMVC是基于方法设计，而Struts2是基于对象</li>
<li>SpringMVC属于Spring大家族中的一员，Spring对于SpringMVC的控制器管理更加方便，而Struts2采用XML配置参数来管理</li>
<li>Struts2中自身提供多种参数接收，其实都是通过ValueStack进行传递和赋值，而SpringMVC是通过方法的参数进行接收</li>
<li>Struts2拥有较多的技术点，比如拦截器、值栈和OGNL表达式，学习成本较高，而SpringMVC相对比较简单</li>
<li>Struts有自己的interceptor拦截机制，SpringMVC使用的是独立的AOP</li>
<li>SpringMVC处理Ajax请求，直接通过返回数据，方法中使用注解@ResponseBody直接转为JSON对象返回，而Struts2是通过插件的方式处理</li>
</ol>
</blockquote>
</li>
<li><h4 id="Spring中的两大核心"><a href="#Spring中的两大核心" class="headerlink" title="Spring中的两大核心"></a>Spring中的两大核心</h4><blockquote>
<ol>
<li><p>IOC（Inversion of Control）或DI（Dependency Injection）</p>
<blockquote>
<p><strong>IOC控制反转：</strong></p>
<p>在spring中BeanFactory是IOC容器的核心接口，负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。XmlBeanFactory实现BeanFactory接口，通过获取xml配置文件数据，组成应用对象及对象间的依赖关系。</p>
<p>Spring中有三种注入方式：set注入、接口注入、构造方法注入</p>
<p>核心原理：配置文件+反射+容器</p>
</blockquote>
</li>
<li><p>AOP面向切面编程：</p>
<blockquote>
<p>使用动态代理的方式在执行前后或出现异常后执行相关逻辑</p>
<p>主要用于：事务、日志、权限校验</p>
</blockquote>
</li>
</ol>
</blockquote>
</li>
<li><h4 id="ORM框架"><a href="#ORM框架" class="headerlink" title="ORM框架"></a>ORM框架</h4><blockquote>
<p>为了解决面向对象与关系数据库存在的互不匹配的现象的框架</p>
</blockquote>
</li>
<li><h4 id="Mybatis和Hibernate区别"><a href="#Mybatis和Hibernate区别" class="headerlink" title="Mybatis和Hibernate区别"></a>Mybatis和Hibernate区别</h4><blockquote>
<p><strong>相同点：</strong></p>
<p>​    都是java中的ORM框架、屏蔽了jdbc api的底层访问细节。</p>
<p>​    mybatis：专注sql本身，需要程序员自己编写sql语句，sql修改、优化比较方便。mybatis是一个不完全的ORM框架，虽然程序员自己写sql，mybatis也可以实现映射（输入映射，输出映射）</p>
<p>​    应用场景：适用需求变化较多的项目，比如：互联网项目。</p>
<p>​    hibernate:是一个标准的ORM框架（对象关系映射）。入门门槛较高，不需要写sql，sql语句自动生成，对sql语句进行优化、修改比较困难。</p>
<p>​    应用场景：适用需求变化不多的中小型项目，比如：后台管理系统，erp，orm，oa等</p>
</blockquote>
</li>
<li><h4 id="Hibernate映射对象的状态"><a href="#Hibernate映射对象的状态" class="headerlink" title="Hibernate映射对象的状态"></a>Hibernate映射对象的状态</h4><blockquote>
<ol>
<li>临时状态(transient)(瞬态)：刚用new 语句创建，还没有被持久化，并且不处于Sesssion 的缓存中。处于临时状态的Java 对象被称为临时对象。</li>
<li>持久化状态(persistent)：已经被持久化，并且加入到Session 的缓存中。处于持久化状态的Java 对象被称为持久化对象。</li>
<li>删除状态(removed)：不再处于Session 的缓存中，并且Session 已经计划将其从数据库中删除。处于删除状态的Java 对象被称为删除对象。</li>
<li>游离状态(detached)：已经被持久化，但不再处于Session 的缓存中。处于游离状态的Java 对象被称为游离对象。</li>
</ol>
<p>下面以具体的代码来说明这四种状态:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>&#123;  </span><br><span class="line">  </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;  </span><br><span class="line">        SessionFactory sessionFactory=HibernateUtil.getSessionFactory();  </span><br><span class="line">        Session session=sessionFactory.openSession(); <span class="comment">// 生成一个session  </span></span><br><span class="line">        session.beginTransaction(); <span class="comment">// 开启事务  </span></span><br><span class="line">          </span><br><span class="line">        Person p1=<span class="keyword">new</span> Person(<span class="string">&quot;天天&quot;</span>,<span class="string">&quot;18&quot;</span>,<span class="string">&quot;3009&quot;</span>); <span class="comment">// 临时对象1  </span></span><br><span class="line">        Person p2=<span class="keyword">new</span> Person(<span class="string">&quot;小李&quot;</span>,<span class="string">&quot;23&quot;</span>,<span class="string">&quot;4009&quot;</span>); <span class="comment">// 临时对象1   </span></span><br><span class="line">        session.save(p1); <span class="comment">// 持久化对象  </span></span><br><span class="line">        session.save(p2); <span class="comment">// 持久化对象  </span></span><br><span class="line">          </span><br><span class="line">        session.delete(p2); <span class="comment">// 删除对象  </span></span><br><span class="line">          </span><br><span class="line">        session.getTransaction().commit(); <span class="comment">// 提交事务  </span></span><br><span class="line">        session.close(); <span class="comment">// 关闭session  </span></span><br><span class="line">          </span><br><span class="line">        System.out.println(p1.getName()); <span class="comment">// 游离对象  </span></span><br><span class="line">        System.out.println(p2.getName()); <span class="comment">// 删除对象  </span></span><br><span class="line">    &#125;     </span><br><span class="line">&#125;  </span><br></pre></td></tr></table></figure></blockquote>
</li>
<li><h4 id="Hibernate缓存机制"><a href="#Hibernate缓存机制" class="headerlink" title="Hibernate缓存机制"></a>Hibernate缓存机制</h4><blockquote>
<p>​    使用缓存是为了降低应用程序对物理数据源访问的频次，从而提高应用程序的运行性能</p>
<p>​    Hibernate缓存分为一级缓存和二级缓存，一级缓存就是Session级别的缓存，在事务范围内有效是,内置的不能被卸载。二级缓存是SesionFactory级别的缓存，从应用启动到应用结束有效。是可选的，默认没有二级缓存，需要手动开启。</p>
<p>什么样的数据适合存放到第二级缓存中？ 　　</p>
<p>​    1) 很少被修改的数据 　帖子的最后回复时间　</p>
<p>​    2) 经常被查询的数据   电商的地点</p>
<p>​    3) 不是很重要的数据，允许出现偶尔并发的数据 　　</p>
<p>​    4) 不会被并发访问的数据 　　</p>
<p>​    5) 常量数据 </p>
<p>扩展：hibernate的二级缓存默认是不支持分布式缓存的。使用memcahe,redis等中央缓存来代替二级缓存。</p>
</blockquote>
</li>
<li><h4 id="webservice使用场景"><a href="#webservice使用场景" class="headerlink" title="webservice使用场景"></a>webservice使用场景</h4><blockquote>
<p>​    webservice是一个SOA（面向服务的编程）的架构，它是不依赖于语言，不依赖于平台，可以实现不同的语言间的相互调用，通过Internet进行基于Http协议的网络应用间的交互。</p>
<ol>
<li><p>异构系统(不同语言)的整合</p>
</li>
<li><p>不同客户端的整合，浏览器、手机端(android,ios.塞班)、微信端、PC端等终端来访问</p>
</li>
<li><p>实实在在的列子：</p>
<p>天气预报：可以通过实现webservice客户端调用远程天气服务实的。 </p>
<p>单点登录：一个服务是所有系统的登录</p>
</li>
</ol>
</blockquote>
</li>
</ol>
<h2 id="服务器及优化"><a href="#服务器及优化" class="headerlink" title="服务器及优化"></a>服务器及优化</h2><ol>
<li><h4 id="Linux常用命令"><a href="#Linux常用命令" class="headerlink" title="Linux常用命令"></a>Linux常用命令</h4><blockquote>
<p>常用：</p>
<p>​    Pwd 获取当前路径</p>
<p>​    Cd 跳转到目录</p>
<p>​    Su -u 切换到管理员</p>
<p>​    Ls ls 列举目录</p>
<p>文件操作命令：</p>
<p>​    文件</p>
<p>​           tail 查看</p>
<p>​           rm -rf </p>
<p>​           vi</p>
<p>​    文件夹</p>
<p>​           mkdir </p>
<p>​           rm -r</p>
</blockquote>
</li>
<li><h4 id="数据库优化"><a href="#数据库优化" class="headerlink" title="数据库优化"></a>数据库优化</h4><blockquote>
<p>做过mysql数据库的优化、其他数据库类似</p>
<p>定位：查找、定位慢查询</p>
<p>优化手段：</p>
<p>​    a) 创建索引：创建合适的索引，我们就可以现在索引中查询，查询到以后直接找对应的记录。</p>
<p>​    b) 分表：当一张表的数据比较多或者一张表的某些字段的值比较多并且很少使用时，采用水平分表和垂直分表来优化</p>
<p>​    c) 读写分离：当一台服务器不能满足需求时，采用读写分离的方式进行集群。</p>
<p>​    d) 缓存：使用redis来进行缓存</p>
<p>​    e) 一些常用优化技巧</p>
<p><a target="_blank" rel="noopener" href="http://www.cnblogs.com/luyucheng/p/6323477.html">优化</a></p>
</blockquote>
</li>
</ol>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">方陈勇</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://fangchenyong.top/2019/07/18/Java-Java%E7%AC%94%E8%AE%B0/">https://fangchenyong.top/2019/07/18/Java-Java%E7%AC%94%E8%AE%B0/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://fangchenyong.top" target="_blank">Joey</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Java/">Java</a></div><div class="post_share"><div class="social-share" data-image="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/2019/07/18/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84-2-%E7%8E%AF%E5%BD%A2%E9%98%9F%E5%88%97/"><img class="prev-cover" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">数组模拟环形队列</div></div></a></div><div class="next-post pull-right"><a href="/2019/06/29/%E9%A1%B9%E7%9B%AE-FangXingMallNote/"><img class="next-cover" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">方兴商城笔记</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span> 相关推荐</span></div><div class="relatedPosts-list"><div><a href="/2021/04/12/Java-深入理解Java虚拟机/" title="深入理解Java虚拟机"><img class="cover" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-04-12</div><div class="title">深入理解Java虚拟机</div></div></a></div><div><a href="/2021/03/20/Java-源码-JDK8-HashMap/" title="JDK8 HashMap源码"><img class="cover" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-03-20</div><div class="title">JDK8 HashMap源码</div></div></a></div><div><a href="/2019/09/06/Java-源码-JDK8-String/" title="JDK8 String源码"><img class="cover" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2019-09-06</div><div class="title">JDK8 String源码</div></div></a></div><div><a href="/2019/08/23/项目-基于Netty+WebSocket简易版微信/" title="基于Netty+WebSocket简易版微信"><img class="cover" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2019-08-23</div><div class="title">基于Netty+WebSocket简易版微信</div></div></a></div><div><a href="/2019/08/23/Java-源码-JDK8-Object/" title="JDK8 Object源码"><img class="cover" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2019-08-23</div><div class="title">JDK8 Object源码</div></div></a></div><div><a href="/2019/07/29/项目-理财产品系统/" title="理财产品系统（慕课网）"><img class="cover" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2019-07-29</div><div class="title">理财产品系统（慕课网）</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="card-info-avatar is-center"><img class="avatar-img" src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/3FD9B055-6361-49B7-B8CE-5BA9144BD27F.JPG" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/><div class="author-info__name">方陈勇</div><div class="author-info__description">一路向前</div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">43</div></a></div><div class="card-info-data-item is-center"><a href="/tags/"><div class="headline">标签</div><div class="length-num">51</div></a></div><div class="card-info-data-item is-center"><a href="/categories/"><div class="headline">分类</div><div class="length-num">53</div></a></div></div><a class="button--animated" id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/fangchenyong"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/fangchenyong" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:1013659102@qq.com" target="_blank" title="Email"><i class="fas fa-envelope"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>公告</span></div><div class="announcement_content">个人笔记，如有疑问请联系 QQ:1013659102。</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#java%E5%9F%BA%E7%A1%80%E7%AC%94%E8%AE%B0"><span class="toc-text">java基础笔记</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%8C%85%E8%A3%85%E7%B1%BB%E5%9E%8B"><span class="toc-text">基本数据类型和包装类型</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#java%E4%B8%AD%E7%9A%84%E9%9B%86%E5%90%88"><span class="toc-text">java中的集合</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ArrayList%E5%92%8CLinkedList%E7%9A%84%E5%8C%BA%E5%88%AB%E5%92%8C%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-text">ArrayList和LinkedList的区别和使用场景</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#HashMap%E5%92%8CHashtable%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">HashMap和Hashtable的区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%8B%B7%E8%B4%9D%E6%96%87%E4%BB%B6%E7%9A%84%E5%B7%A5%E5%85%B7%E7%B1%BB%E4%BD%BF%E7%94%A8%E5%AD%97%E8%8A%82%E6%B5%81%E8%BF%98%E6%98%AF%E5%AD%97%E7%AC%A6%E6%B5%81"><span class="toc-text">实现一个拷贝文件的工具类使用字节流还是字符流</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%BA%BF%E7%A8%8B%E7%9A%84%E5%87%A0%E7%A7%8D%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F"><span class="toc-text">线程的几种实现方式</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%BA%BF%E7%A8%8B%E6%B1%A0"><span class="toc-text">线程池</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%9A%84%E9%A3%8E%E9%99%A9%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BD%BF%E7%94%A8%E7%BA%BF%E7%A8%8B%E6%B1%A0"><span class="toc-text">使用线程池的风险，为什么使用线程池</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F"><span class="toc-text">设计模式</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#javaWeb%E7%AC%94%E8%AE%B0"><span class="toc-text">javaWeb笔记</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Http-Get%E5%92%8CPost%E8%AF%B7%E6%B1%82%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">Http Get和Post请求的区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#servlet%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-text">servlet的理解</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#servlet%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="toc-text">servlet的生命周期</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Servlet-API%E4%B8%ADforward-%E5%92%8Credirect-%E5%8C%BA%E5%88%AB"><span class="toc-text">Servlet API中forward() 和redirect()区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Session%E5%92%8CCookie%E5%8C%BA%E5%88%AB"><span class="toc-text">Session和Cookie区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#MVC%E7%9A%84%E5%90%84%E9%83%A8%E5%88%86%E9%83%BD%E6%9C%89%E5%93%AA%E4%BA%9B%E6%8A%80%E6%9C%AF%E6%9D%A5%E5%AE%9E%E7%8E%B0"><span class="toc-text">MVC的各部分都有哪些技术来实现</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AC%94%E8%AE%B0"><span class="toc-text">数据库笔记</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%95%B0%E6%8D%AE%E5%BA%93%E5%88%86%E7%B1%BB"><span class="toc-text">数据库分类</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%89%E8%8C%83%E5%BC%8F"><span class="toc-text">关系型数据库三范式</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BA%8B%E5%8A%A1%E5%9B%9B%E4%B8%AA%E5%9F%BA%E6%9C%AC%E7%89%B9%E5%BE%81ACID%E7%89%B9%E6%80%A7"><span class="toc-text">事务四个基本特征ACID特性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#MySql%E6%95%B0%E6%8D%AE%E5%BA%93%E9%BB%98%E8%AE%A4%E7%9A%84%E6%9C%80%E5%A4%A7%E8%BF%9E%E6%8E%A5%E6%95%B0"><span class="toc-text">MySql数据库默认的最大连接数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#MySql%E5%88%86%E9%A1%B5%E3%80%81Oracle%E5%88%86%E9%A1%B5%E5%92%8CSqlServer%E5%88%86%E9%A1%B5"><span class="toc-text">MySql分页、Oracle分页和SqlServer分页</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%A7%A6%E5%8F%91%E5%99%A8%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-text">触发器使用场景</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%89%8D%E7%AB%AF%E7%AC%94%E8%AE%B0"><span class="toc-text">前端笔记</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A1%86%E6%9E%B6%E7%AC%94%E8%AE%B0"><span class="toc-text">框架笔记</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#SpringMVC%E6%89%A7%E8%A1%8C%E6%B5%81%E7%A8%8B"><span class="toc-text">SpringMVC执行流程</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Struts2%E5%92%8CSpringMVC%E5%8C%BA%E5%88%AB"><span class="toc-text">Struts2和SpringMVC区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Spring%E4%B8%AD%E7%9A%84%E4%B8%A4%E5%A4%A7%E6%A0%B8%E5%BF%83"><span class="toc-text">Spring中的两大核心</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ORM%E6%A1%86%E6%9E%B6"><span class="toc-text">ORM框架</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Mybatis%E5%92%8CHibernate%E5%8C%BA%E5%88%AB"><span class="toc-text">Mybatis和Hibernate区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Hibernate%E6%98%A0%E5%B0%84%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%8A%B6%E6%80%81"><span class="toc-text">Hibernate映射对象的状态</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Hibernate%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6"><span class="toc-text">Hibernate缓存机制</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#webservice%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-text">webservice使用场景</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%8F%8A%E4%BC%98%E5%8C%96"><span class="toc-text">服务器及优化</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4"><span class="toc-text">Linux常用命令</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BC%98%E5%8C%96"><span class="toc-text">数据库优化</span></a></li></ol></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/2021/05/06/%E7%AE%97%E6%B3%95-%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F/" title="算法"><img src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="算法"/></a><div class="content"><a class="title" href="/2021/05/06/%E7%AE%97%E6%B3%95-%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F/" title="算法">算法</a><time datetime="2021-05-05T16:00:00.000Z" title="发表于 2021-05-06 00:00:00">2021-05-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/05/06/%E7%AE%97%E6%B3%95-%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F/" title="选择排序"><img src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="选择排序"/></a><div class="content"><a class="title" href="/2021/05/06/%E7%AE%97%E6%B3%95-%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F/" title="选择排序">选择排序</a><time datetime="2021-05-05T16:00:00.000Z" title="发表于 2021-05-06 00:00:00">2021-05-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/04/12/Java-%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E8%99%9A%E6%8B%9F%E6%9C%BA/" title="深入理解Java虚拟机"><img src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="深入理解Java虚拟机"/></a><div class="content"><a class="title" href="/2021/04/12/Java-%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E8%99%9A%E6%8B%9F%E6%9C%BA/" title="深入理解Java虚拟机">深入理解Java虚拟机</a><time datetime="2021-04-11T16:00:00.000Z" title="发表于 2021-04-12 00:00:00">2021-04-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/03/21/%E9%9D%A2%E8%AF%95-%E5%B9%B6%E5%8F%91%E3%80%81%E5%A4%9A%E7%BA%BF%E7%A8%8B/" title="面试题-并发编程"><img src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="面试题-并发编程"/></a><div class="content"><a class="title" href="/2021/03/21/%E9%9D%A2%E8%AF%95-%E5%B9%B6%E5%8F%91%E3%80%81%E5%A4%9A%E7%BA%BF%E7%A8%8B/" title="面试题-并发编程">面试题-并发编程</a><time datetime="2021-03-20T16:00:00.000Z" title="发表于 2021-03-21 00:00:00">2021-03-21</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/03/20/%E9%9D%A2%E8%AF%95-%E9%9B%86%E5%90%88/" title="面试题-集合框架"><img src="https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="面试题-集合框架"/></a><div class="content"><a class="title" href="/2021/03/20/%E9%9D%A2%E8%AF%95-%E9%9B%86%E5%90%88/" title="面试题-集合框架">面试题-集合框架</a><time datetime="2021-03-19T16:00:00.000Z" title="发表于 2021-03-20 00:00:00">2021-03-20</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('https://fangchenyong.oss-cn-hangzhou.aliyuncs.com/BEF238F4E59CF4D91A694FE9C5DBC030.JPG')"><div id="footer-wrap"><div class="copyright">&copy;2019 - 2021 By 方陈勇</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text">人生没有退路！</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><div class="js-pjax"></div><script id="canvas_nest" defer="defer" color="0,0,255" opacity="0.7" zIndex="-1" count="99" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-nest.min.js"></script></div></body></html>